package com.mingqijia.gassafety.authority.dal.handler;

import com.mingqijia.gassafety.authority.api.req.resource.*;
import com.mingqijia.gassafety.authority.api.resp.resource.ResourceLiteRespDTO;
import com.mingqijia.gassafety.authority.api.resp.resource.ResourceRespDTO;
import com.mingqijia.gassafety.authority.dal.command.CreateResourceCommand;
import com.mingqijia.gassafety.authority.dal.command.QueryResourceCommand;
import com.mingqijia.gassafety.authority.dal.command.RemoveResourceCommand;
import com.mingqijia.gassafety.authority.dal.command.UpdateResourceCommand;
import com.mingqijia.gassafety.db.entity.auth.ResourceEntry;
import com.mingqijia.gassafety.shared.utils.MappingTools;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 对象转换接口
 * @author Damon S.
 * @version v1.0.1
 * @date 2020年01月09日 20:37
 */
@Mapper(componentModel = "spring", uses = MappingTools.class)
@ConditionalOnMissingBean(ResourceTranslatorImpl.class)
public interface ResourceTranslator {

    ResourceRespDTO toRespDTO(ResourceEntry entry);

    @Mapping(source = "id", target = "resId")
    ResourceLiteRespDTO toLiteRespDTO(ResourceEntry entry);

    ResourceEntry toEntry(CreateResourceCommand command);

    @Mapping(source = "resId", target = "id")
    ResourceEntry toEntry(UpdateResourceCommand command);

    QueryResourceCommand toCommand(QueryResourceReqDTO req);

    CreateResourceCommand toCommand(CreateFuncResourceReqDTO req);

    CreateResourceCommand toCommand(CreateMenuResourceReqDTO req);

    UpdateResourceCommand toCommand(UpdateFuncResourceReqDTO req);

    UpdateResourceCommand toCommand(UpdateMenuResourceReqDTO req);

    @Mapping(source = "resIds", target = "id")
    ResourceEntry toEntry(RemoveResourceCommand command);

    default List<ResourceRespDTO> toRespDTO(List<ResourceEntry> entries) {
        return Optional.ofNullable(entries)
                .orElse(Collections.emptyList())
                .stream().map(this::toRespDTO)
                .collect(Collectors.toList());
    }

    default List<ResourceLiteRespDTO> toLiteRespDTO(List<ResourceEntry> entries) {
        return Optional.ofNullable(entries)
                .orElse(Collections.emptyList())
                .stream().map(this::toLiteRespDTO)
                .collect(Collectors.toList());
    }
}
